package main

import (
	"fmt"
	"reflect"
	"sync"
	"time"
)
//此处更改函数类型
type Method func(int,*int)

//函数信息包括函数变量和参数表
type MethodInfo struct {
	ind int
	name Method
	args []interface{}
	sign int//0:未运行；1：正在运行；2：运行完成
}
//线程池
type RunPool struct {
	MethIndex int
	MaxCount int
	Sum int
	Count int
	stop bool
	fmutex sync.RWMutex
	methods []*MethodInfo
}
//开始
func (this *RunPool)init(sum int){
	if sum>400{
		sum=400
	}
	fmt.Println("开始运行线程池")
	this.fmutex.Lock()
	this.stop=false
	this.Count=0
	this.Sum=sum
	this.MaxCount=400
	this.MethIndex=0
	this.fmutex.Unlock()
	fmt.Println("线程池初始化设置完成开始，开始运行")
	for ;this.stop==false ;  {
		this.proc()
		//fmt.Print("1")
	}
	fmt.Println("out")
}
//关闭
func (this *RunPool)close(){
	//timeout:=make(chan bool,1)
	cc:=make(chan int,1)
	//defer close(timeout)
	defer close(cc)
	//go func() {
	//	time.Sleep(4e8)
	//	timeout<-true
	//}()
	go this.closeIn(cc)
	_=<-cc
	//select {
	//case <-cc:
	//	//fmt.Println("结束成功!!!!!!")
	//case <-timeout:
	//	//fmt.Println("timeout")
	//}
}
//关闭
func (this *RunPool)closeIn(cc chan int){
	signClose:=true
	for signClose {
		if len(this.methods)==0{ signClose=false }
	}
	fmt.Println("最终数",this.Count,len(this.methods))
	fmt.Println("开始关闭")
	this.stop=true
	fmt.Println("关闭设置完成")
	cc<-1
}
//添加
func (this *RunPool)add(name Method,args []interface{})(sign bool,err error){
	this.fmutex.Lock()
	defer func() { // 必须要先声明defer，否则不能捕获到panic异常
		if err := recover(); err != nil {
			sign=false
		}
	}()
	fmt.Println("添加方法开始")
	var methInf=&MethodInfo{this.MethIndex,name,args,0}

	this.methods=append(this.methods, methInf)
	this.MethIndex=this.MethIndex+1
	sign=true
	fmt.Println("添加方法结束",methInf.ind)
	this.fmutex.Unlock()
	return
}
//处理
func (this *RunPool)proc(){
	fmt.Println("开始处理过程")
	for _,meth:=range this.methods{
		switch meth.sign{
			//运行未运行
			case 0:{
				//fmt.Println(len(this.methods))
				if this.Count<this.Sum && len(this.methods)<this.MaxCount{
					fmt.Println("运行新线程")
					go methodRun(meth)
					this.fmutex.Lock()
					this.Count=this.Count+1
					this.fmutex.Unlock()
				}
			}
			//对正在运行什么也不做
			case 1:{}
			//删除已运行
			case 2:{
				fmt.Println("结束旧线程",meth.ind)
				var methodsTemp []*MethodInfo
				for _,v:=range this.methods {
					if(v.ind!=meth.ind){
						methodsTemp=append(methodsTemp,v)
					}
				}
				this.fmutex.Lock()
				this.methods=methodsTemp
				this.Count=this.Count-1
				this.fmutex.Unlock()
				fmt.Println("结束中数",this.Count,this.methods)
			}
		}
	}
	//fmt.Println("处理过程结束")
}
//函数运行
func methodRun(meth *MethodInfo){
	fmt.Println("运行方法",meth.ind)
	meth.sign=1
	fun := reflect.ValueOf(meth.name)
	var listVal []reflect.Value
	for _,v:=range meth.args{
		listVal=append(listVal, reflect.ValueOf(v))
	}
	fun.Call(listVal)
	fmt.Println("运行方法结束",meth.ind)
	meth.sign=2
}

var method2=func (val int,res *int){
	for i:=0;i<10 ;i++  {
		val+=i
	}
	time.Sleep(5)
	*res=val
}

func main()  {
	t1 := time.Now()
	var pool *RunPool=new(RunPool)
	go pool.init(400)
	if false{
		fmt.Println("begin")
		var val1 int
		var val2 int
		var val3 int
		var args1=[]interface{}{2,&val1}
		var args2=[]interface{}{3,&val2}
		var args3=[]interface{}{4,&val3}
		pool.add(method2,args1)
		pool.add(method2,args2)
		pool.add(method2,args3)

	}
	if true{
		for i:=0;i<400 ;i++ {
			var val1 int
			var args1 = []interface{}{2, &val1}
			pool.add(method2, args1)
		}
	}
	pool.close()
	//fmt.Println("end",val1,val2,val3)
	elapsed := time.Since(t1)
	fmt.Println("App elapsed: ", elapsed)
	//,string(val2),string(val3)
}





//func main_testreflect(){
//runtime.GOMAXPROCS(runtime.NumCPU())
////初始化线程
//v := reflect.ValueOf(method1)
//var list []interface{}=[]interface{}{2,3}
//var listVal []reflect.Value
//for _,v:=range list{
//	listVal=append(listVal, reflect.ValueOf(v))
//}
//r:=v.Call(listVal)


//switch reflect.Value.Type(r){
//case Type.Int:
//	fmt.Println(v,"int")
//case string:
//	fmt.Println(v,"string")
//case float64:
//	fmt.Println(v,"float")
//default:
//	fmt.Println(v,"other")
//}
//for _,r:=range r{
//	fmt.Println(reflect.Value.Int(r))
//}
//}
//func (this *RunPool1)init1(sum int){
//	this.stop=false
//	this.Count=0
//	this.Sum=sum
//	for ;this.stop==false ;  {
//		fmt.Print("1")
//	}
//	fmt.Println("out")
//}
////关闭
//func (this *RunPool1)close1(cc chan int){
//	time.Sleep(50)
//	fmt.Println("in")
//	this.stop=true
//	fmt.Println("set")
//	cc<-1
//}
//func (this *RunPool1)Run1(method func(),args map[string]interface{}){
//	if this.Count+1<this.Sum {
//		//runProc(method,args)
//	}else{
//		time.Sleep(100)
//		//递归调用会耗尽资源
//		this.Run(method,args)
//	}
//}
//func runProc1(method func(),args []interface{}){
//	ch:=make(chan bool,1)
//	timeout:=make(chan bool,1)
//	defer close(timeout)
//	defer close(ch)
//	go func() {
//		time.Sleep(4e8)
//		timeout<-true
//	}()
//	go func() {
//
//		ch<-true
//	}()
//	select {
//	case <-ch:
//		fmt.Println("运行成功")
//	case <-timeout:
//		fmt.Println("timeout")
//	}
//}
//func method11(val,a int)(int,int){
//	for i:=0;i<100 ;i++  {
//		val+=i
//	}
//	return val,a
//}